package com.qhx.rtkcloud.ntrip;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.concurrent.LinkedBlockingQueue;

import static com.qhx.rtkcloud.ntrip.GgaSocket.executorService;

public class GgaSocketQueue {

    private ServerSocket ServerSocket;
    private Socket cloudSocket;

    //基站发送到云端，云端存储到该队列，本地连接从该队列中取数据
    private LinkedBlockingQueue<byte[]> QueueOne;


    private Socket localSocket;


    public GgaSocketQueue() {
    }

    public GgaSocketQueue(ServerSocket serverSocket) {
        this.ServerSocket = serverSocket;
        this.QueueOne = new LinkedBlockingQueue<byte[]>();
        waitingForConnection();
    }


    public java.net.ServerSocket getServerSocket() {
        return ServerSocket;
    }

    public void setServerSocket(java.net.ServerSocket serverSocket) {
        ServerSocket = serverSocket;
    }

    public Socket getCloudSocket() {
        return cloudSocket;
    }

    public void setCloudSocket(Socket cloudSocket) {
        this.cloudSocket = cloudSocket;
    }

    public LinkedBlockingQueue<byte[]> getQueueOne() {
        return QueueOne;
    }

    public void setQueueOne(LinkedBlockingQueue<byte[]> queueOne) {
        QueueOne = queueOne;
    }

    public Socket getLocalSocket() {
        return localSocket;
    }

    public void setLocalSocket(Socket localSocket) {
        this.localSocket = localSocket;
    }


    public void waitingForConnection() {
        executorService.submit(() -> {
            while (true) {
                try {
                    Socket socket = ServerSocket.accept();
                    receiveData(socket);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
    }

    public void receiveData(Socket socket) {
        executorService.submit(() -> {
                    byte[] buffer = new byte[10240];
                    InputStream inputStream = null;
                    try {
                        inputStream = socket.getInputStream();
                        while (true) {
                            int read = inputStream.read(buffer);
                            if (read > 0) {
                                byte[] bytes1 = Arrays.copyOfRange(buffer, 0, read);
                                String gpggaSentence = new String(bytes1, StandardCharsets.UTF_8);
                                //从本地客户端连接
                                if (gpggaSentence.equals("localClient")) {
                                    localSocket = socket;
                                    //本地socket从队列中取出数据
                                    fromQueueOneTaskToLocalSocket();
                                    break;
                                } else {
                                    cloudSocket = socket;
                                    if (localSocket != null){
                                        System.out.println("将数据放入到队列" + bytes1);
                                        QueueOne.offer(bytes1);
                                    }
                                    buffer = new byte[10240];
                                }
                            }else {
                                if (cloudSocket != null){
                                    cloudSocket.close();
                                }
                                cloudSocket = null;
                                break;
                            }
                        }
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        );
    }

    private void fromQueueOneTaskToLocalSocket() {
        executorService.submit(()->{
            try {
                OutputStream outputStream = localSocket.getOutputStream();
                while (true){
                    byte[] bytes = QueueOne.take();
                    System.out.println("从队列中取出数据");
                    outputStream.write(bytes);
                    outputStream.flush();
                }
            } catch (Exception e) {
                try {
                    localSocket.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                localSocket = null;
                return;
            }
        });
    }
}
